import reflectDemo.Dog;
import reflectDemo.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {

    //通过class对象来创建student对象。
    public static void reﬂectNewInstance() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class c3 = null ;
        c3 =     Class.forName("reflectDemo.Student");
        //要通过c3对象来调用实例化对象的方法
        Student student1 = (Student) c3.newInstance();
        System.out.println(student1);

    }

    // 反射私有的构造方法 屏蔽内容为获得公有的构造方法
    public static void reﬂectPrivateConstructor(){
        Class c3 = null ;
        try {
            c3 =     Class.forName("reflectDemo.Student");
            //调用getConstructor方法，参数为

            Constructor<Student> constructor =  c3.getDeclaredConstructor(String.class,int.class);
           //在获取了构造方法之后呢？
            constructor.setAccessible(true);
            //直接调用此构造方法，为对象赋值
         Student student2 =    constructor.newInstance("张三",15);
            System.out.println(student2);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
// 反射私有属性
public static void reflectPrivateField(){
    Class c3 = null ;
    try {
        c3 =     Class.forName("reflectDemo.Student");
        Field field =  c3.getDeclaredField("name");
        //我们可以修改这个私有属性的值
        field.setAccessible(true);
        //还需要有一个Student对象，
        Student student3 = (Student)c3.newInstance();
        field.set(student3,"张三");
        System.out.println(student3);

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}
public static void reflectPrivateMethod(){
        Class  c4 = null;
    try {
        c4 = Class.forName("reflectDemo.Student");
                                                                            //在有参数时一定要加上参数类型的class
        Method method = c4.getDeclaredMethod("eat",String.class);
        Student student4 = (Student) c4.newInstance();
        method.setAccessible(true);
        method.invoke(student4, "i am eat");

    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}






    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //通过class对象创建一个学生对象
       //   reﬂectNewInstance();
       reﬂectPrivateConstructor();
     //   reflectPrivateField();
 //       reflectPrivateMethod();
        //Class c1 = new Class();
    }

    public static void main1(String[] args) throws ClassNotFoundException {
      /*  int i = 0;
        System.out.println( i = 5);*/
       //关于Class类的使用
        //要创建class对象有三种方式：
        //第一种：调用Class方法
        Student student = new Student();
        //getClass方法也是用c/c++代码实现的
       Class<Student> c1 = (Class<Student>) student.getClass();
       //第二种：直接调用类名的class属性,但是我们并没有在Student中定义class属性
        //这说明每一个方法都有一个默认的class属性
       //  Class c2 = Student.class;
         Class c2 = Dog.class;
      //第三种：通过class对象的ForName方法来获取，
        Class c3 = null ;
        c3 =     Class.forName("reflectDemo.Student");
         //判断这三个class对象是不是同一个对象。
        System.out.println(c1 ==c2);
        System.out.println(c1==c3);
        System.out.println(c2==c3);
//   打印值均为true,说明c1,c2,c3其实均是一个对象。
        /*Student student1 = new Student();
        Student student2 = new Student();
        Student student3 = new Student();
        System.out.println(student1 ==student2);
        System.out.println(student2==student3);
        System.out.println(student1==student3);*/
//打印的结果均为false，Class对象特殊在哪里？
        //每一个类都只会被加载一次，故每一个类对应的class对象只有一个，

        //关于反射类的使用，
        //对于类加载器的使用，类加载器是硬件设施还是软件设施？
        //










































    }
}
